/*
 * @lc app=leetcode.cn id=92 lang=javascript
 *
 * [92] 反转链表 II
 */

// @lc code=start
/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} head
 * @param {number} left
 * @param {number} right=
 * @return {ListNode}
 */

// var reserve = function(head, n) {
//   let pre = null, cur = head;
//   while(n--) {
//     [cur.next, pre, cur] = [pre, cur, cur.next]
//   }
//   head.next = cur;
//   return pre;
// }
// var reverseBetween = function(head, left, right) {
//   if(!head) return null;
//   let ret = new ListNode(-1, head);
//   let pre = ret;
//   let cnt = right - left + 1;
//   while(--left){
//     pre = pre.next;
//   }
//   pre.next = reserve(pre.next, cnt)
//   return ret.next;
// };

/**
 * 复习 2021-08-04
 */
// var reverse = function(head, n){
//   let pre = null, cur = head;
//   while(n--){
//     [cur.next, pre, cur] = [pre, cur, cur.next];
//   }
//   head.next = cur;
//   return pre;
// }
// var reverseBetween = function(head, left, right) {
//   if(!head) return head;
//   let ret = new ListNode(null, head);
//   let pre = ret;
//   let cnt = right - left + 1;
//   while(--left){ 
//     pre = pre.next;
//   }
//   pre.next = reverse(pre.next, cnt);
//   return ret.next;
// }

// 一起学算法-1
// 如果有可能更换头节点，就需要用到虚拟头节点
const reserve = function (head, n) {
  if (!head) return null;
  let pre = null, cur = head;
  while (cur && n-- > 0) {
    [cur.next, pre, cur] = [pre, cur, cur.next];
  }
  // 此时head为尾节点， cur为下一段的头节点
  head.next = cur;
  return pre;
}
var reverseBetween = function (head, left, right) {
  if (!head || !head.next) return head;
  if (right - left === 0) return head;
  let l = left;

  let ret = new ListNode(null, head);
  let pre = ret;
  while (--l) {
    pre = pre.next;
  }
  // 3个节点需要修改两个节点的指针
  let temp = reserve(pre.next, right - left + 1);
  pre.next = temp;

  return ret.next;
}
// @lc code=end

